<?php
namespace App\Service\Wx;

class Pkcs7Encoder
{

    private $app_id;

    private $session_key;

    public function __construct($app_id, $session_key)
    {
        $this->app_id = $app_id;
        $this->session_key = $session_key;
    }

    /**
     * 对解密后的明文进行补位删除
     * @param decrypted 解密后的明文
     * @return 删除填充补位后的明文
     */
    private function decode($text)
    {

        $pad = ord(substr($text, -1));
        if ($pad < 1 || $pad > 32) {
            $pad = 0;
        }
        return substr($text, 0, (strlen($text) - $pad));
    }

    /**
     * 微信小程序加密数据解密
     * @param string $encrypted_data 包括敏感数据在内的完整用户信息的加密数据
     * @param string $iv 加密算法的初始向量
     * @return array
     */
    public function decrypt($encrypted_data, $iv)
    {

        if (strlen($this->session_key) != 24) {
            return ['code' => 100001, 'message' => 'session_key不正确'];
        }
        $aes_key = base64_decode($this->session_key);

        if (strlen($iv) != 24) {
            return ['code' => 100002, 'message' => 'iv不正确'];
        }
        $aes_iv = base64_decode($iv);

        $aes_cipher=base64_decode($encrypted_data);

        try {

            $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');

            mcrypt_generic_init($module, $aes_key, $aes_iv);

            //解密
            $decrypted = mdecrypt_generic($module, $aes_cipher);
            mcrypt_generic_deinit($module);
            mcrypt_module_close($module);

        } catch (Exception $e) {
            return ['code' => 100003, 'message' => '解密失败'];
        }

        try {
            //去除补位字符
            $result = $this->decode($decrypted);
        } catch (Exception $e) {
            return ['code' => 100003, 'message' => '解密失败'];
        }

        $res = json_decode($result, true);
        if ( $res == NULL ) {
            return ['code' => 100003, 'message' => '解密失败'];
        }
        if ( $res['watermark']['appid'] != $this->app_id ) {
            return ['code' => 100003, 'message' => '解密失败'];
        }
        unset($res['watermark']);

        return ['code' => 200, 'message' => 'ok', 'data' => $res];

    }


}